package com.satalyst.util;

import org.apache.commons.lang3.StringUtils;

/**
 * A utility class that implements various precondition assertion routines that can be used to validate arguments.
 *
 * @author Michael Fazio
 */
public final class Preconditions {

    public static <T> T nonNull(T value) throws NullPointerException {
        if(value == null) {
            throw new NullPointerException("unexpected null value");
        }
        return value;
    }
    
    public static String nonEmpty(String value) throws IllegalArgumentException {
        if(StringUtils.isEmpty(value)) {
            throw new IllegalArgumentException("unexpected empty string");
        }
        return value;
    }
    
    public static String empty(String value) throws IllegalArgumentException {
        if(StringUtils.isNotEmpty(value)) {
            throw new IllegalArgumentException("unexpected non-empty string");
        }
        return value;
    }

    public static String nonBlank(String value) throws IllegalArgumentException {
        if(StringUtils.isBlank(value)) {
            throw new IllegalArgumentException("unexpected blank string");
        }
        return value;
    }

    public static String blank(String value) throws IllegalArgumentException {
        if(StringUtils.isNotBlank(value)) {
            throw new IllegalArgumentException("unexpected non-blank string");
        }
        return value;
    }
    
    public static String exactLength(String value, int length) throws IllegalArgumentException {
        if(value.length() != length) {
            throw new IllegalArgumentException("expected string length of " + length + ", actual was " + value.length());
        }
        return value;
    }
    
    public static String minLength(String value, int min) throws IllegalArgumentException {
        if(value.length() < min) {
            throw new IllegalArgumentException("expected minimum string length of " + min + ", actual was" + value.length());
        }
        return value;
    }
    
    public static String maxLength(String value, int max) throws IllegalArgumentException {
        if(value.length() > max) {
            throw new IllegalArgumentException("expected maximum string length of " + max + ", actual was " + value.length());
        }
        return value;
    }
    
    public static String betweenLength(String value, int min, int max) throws IllegalArgumentException {
        if(value.length() < min || value.length() > max) {
            throw new IllegalArgumentException("expected string length between " + min + " and " + max + "inclusive, actual was " + value.length());
        }
        return value;
    }

    public static long exact(long value, long exact) throws IllegalArgumentException {
        if(value != exact) {
            throw new IllegalArgumentException("expected value equal to " + exact + ", actual " + value);
        }
        return value;
    }
    
    public static long lessThan(long value, long max) throws IllegalArgumentException {
        if(value > max) {
            throw new IllegalArgumentException("expected value less than " + max + ", actual was " + value);
        }
        return value;
    }

    public static long greaterThan(long value, long min) throws IllegalArgumentException {
        if(value < min) {
            throw new IllegalArgumentException("expected value greater than " + min + ", actual was " + value);
        }
        return value;
    }

    public static long between(long value, long min, long max) throws IllegalArgumentException {
        if(value < min || value > max) {
            throw new IllegalArgumentException("expected value between " + min + " and max " + max + " inclusive, actual was " + value);
        }
        return value;
    }

    /**
     * Private constructor to prevent instantiation.
     */
    private Preconditions() {

    }
    
}
